package vsqlbuilder.gui;

import static vsqlbuilder.Utils.MINIFONT;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import vsqlbuilder.logic.Column;
import vsqlbuilder.logic.LogicModel;
import vsqlbuilder.logic.Schema;
import vsqlbuilder.logic.Table;
import vsqlbuilder.logic.sql.Query;
import vsqlbuilder.logic.sql.QueryTable;



public class ColumnsTreeDialog extends JDialog {

	static final long serialVersionUID = 0L; // TODO [low]: temporary fix, must be
												// change to correct one

	private static final int DIALOG_WIDTH = 250;

	private static final int DIALOG_HEIGHT = 100;

	private static final int BORDER_THICKNESS = 2;

	private static final Color BLACK_COLOR = new Color(60, 60, 60);

		
	private JPanel selTreePanel;
	private JScrollPane selTreeScrollPane;
	private JTree selectionTree; 
	private DefaultMutableTreeNode selectionTreeTopNode = null;
	private final JPopupMenu selTreePopup;
	private LogicModel DatabaseLogic;
	private Query query;
	private JLabel dataLabel; 
	private JButton cancelButton;
	

	public ColumnsTreeDialog(JFrame owner,MainController controller) {
		super(owner, true);
		this.DatabaseLogic=controller.Logic;
		this.query=controller.Model.QueryStatment;
		setBackground(Color.WHITE);
		setUndecorated(true);

		setSize(DIALOG_WIDTH, DIALOG_HEIGHT);
		setLocationRelativeTo(null);
		this.setModal(true);
		cancelButton= new JButton("Cancel");
		ActionListener al= new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				ColumnsTreeDialog.this.dataLabel.setText("Click to select Column...");
				ColumnsTreeDialog.this.setVisible(false);
			}
		};
		cancelButton.addActionListener(al);


		Container contentPane = getContentPane();
		contentPane.setLayout(new BorderLayout());
		
		//Create Selection Tree for Table's Columns
		selTreePanel=  getContent();//new JPanel();
		selTreePanel.setLayout(new BorderLayout());
		selTreeScrollPane = new JScrollPane();
		selectionTree = new JTree();
		DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) selectionTree.getCellRenderer();
		renderer.setFont(MINIFONT);
		
		
		
		selTreePanel.add(selTreeScrollPane);
		Dimension selTreeSize = new Dimension(200,800);
		selectionTree.setPreferredSize(selTreeSize);
		selectionTree.setMinimumSize(selTreeSize);
		selectionTree.setMaximumSize(selTreeSize);
		selectionTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		selectionTreeTopNode = (DefaultMutableTreeNode) selectionTree.getModel().getRoot();
		selTreeScrollPane.getViewport().add(selectionTree);
		selTreePopup = new JPopupMenu();
		selTreePopup.add(selTreePanel);
		selTreePopup.setPreferredSize(selTreeSize);
		selTreePopup.setMinimumSize(selTreeSize);
		selTreePopup.setMaximumSize(selTreeSize);
		selTreePopup.pack();
		contentPane.add(cancelButton,BorderLayout.NORTH);
		contentPane.add(selTreePanel,BorderLayout.CENTER);
		contentPane.validate();
		
		
		
		MouseListener ml = new MouseListener(){
			public void mouseClicked(MouseEvent e){
				if(e.getClickCount()>=2){
					TreePath selPath = selectionTree.getPathForLocation(e.getX(), e.getY());
					selectionTree.setSelectionPath(selPath);
					String s="Click to select Column...";
					try {
						//TODO [low]: validate with instanceof the classes before do it anything
						DefaultMutableTreeNode node = (DefaultMutableTreeNode) selPath.getLastPathComponent();
						if(node.isLeaf()){
							DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) node.getParent();
							DefaultMutableTreeNode parentParentNode = (DefaultMutableTreeNode) parentNode.getParent();
							s = (String) parentParentNode.getUserObject();
							s += "."+(String) parentNode.getUserObject();
							s += "."+(String) node.getUserObject();
							ColumnsTreeDialog.this.setVisible(false);
							}
					} catch (Exception E) {
						System.out
								.println("Error selecting column of Jtree for tab columns jtree");
					}
					ColumnsTreeDialog.this.dataLabel.setText(s);
				}
			}
			public void mouseReleased(MouseEvent e){}
			public void mouseExited(MouseEvent e){}
			public void mouseEntered(MouseEvent e){}
			public void mousePressed(MouseEvent e){}
		};
		
		selectionTree.addMouseListener(ml);
		
		
	}

	public void setVisible(boolean b, int x, int y,JLabel dataLabel){
		this.constructTree();
		this.dataLabel=dataLabel;
		this.setLocation(x,y);
		this.setVisible(b);
		
	}
	
	@SuppressWarnings("serial")
	private JPanel getContent() {
		JPanel panel = new JPanel() {

			protected void paintComponent(Graphics g) {

				Graphics2D g2 = (Graphics2D) g;
				g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
						RenderingHints.VALUE_ANTIALIAS_ON);
				g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
						RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

				super.paintComponent(g);

				g2.setColor(BLACK_COLOR);
				g2.fillRect(0, 0, DIALOG_WIDTH, BORDER_THICKNESS);
				g2.fillRect(0, 0, BORDER_THICKNESS, DIALOG_HEIGHT);
				g2.fillRect(0, DIALOG_HEIGHT - BORDER_THICKNESS, DIALOG_WIDTH,
						BORDER_THICKNESS);
				g2.fillRect(DIALOG_WIDTH - BORDER_THICKNESS, 0,
						BORDER_THICKNESS, DIALOG_WIDTH);
			}
		};
		panel.setLayout(new BorderLayout());
		panel.setBackground(Color.WHITE);
		return panel;
	}

	public void constructTree(){
		this.selTreeScrollPane.getVerticalScrollBar().setValue(0);
		//First Empty the Tree
		if(selectionTreeTopNode!=null){
			selectionTreeTopNode.removeAllChildren();			
		}
		DefaultTreeModel model = (DefaultTreeModel) selectionTree.getModel();
		model.reload();
		
		//TODO [Very low]: Replace this default model with a custom model for the tree
		selectionTreeTopNode.setUserObject("Schemas");
		DefaultMutableTreeNode schemaNode,tableNode,columnNode,tempNode;

			//TODO [Very low]: Optimize this function because this must be done in a better way
			for (QueryTable qt : query.getTablesList()) {
				tableNode = new DefaultMutableTreeNode(qt.getTableName());
				//get columns for each table used in the query [searching the table in the schema and later searching for their columns]
				//Don't use QueryTable Structure because this only have selected columns for query info
				for (Schema s : this.DatabaseLogic.schemas) {
					schemaNode = null;
					if(s.getName().equalsIgnoreCase(qt.getOwnerSchema())){
						//search to see if the schemaNode exists before adding [exists use, if not exists then create schema node]
						int numChildren = selectionTreeTopNode.getChildCount();
						if(numChildren>0){
							for(int i=0;i<numChildren;i++){
								tempNode=(DefaultMutableTreeNode) selectionTreeTopNode.getChildAt(i);
								String tempSchemaName = (String)tempNode.getUserObject();
								if(tempSchemaName.equalsIgnoreCase(s.getName())){
									schemaNode=tempNode;	
								}
							}
						}
						//If not found this schema name then create it.
						if(schemaNode==null){
							schemaNode = new DefaultMutableTreeNode(s.getName());							
						}
						selectionTreeTopNode.add(schemaNode);
						for (Table t : s.tables) {
							if(t.getName().equalsIgnoreCase(qt.getTableName())){
								schemaNode.add(tableNode);
								for (Column c : t.columns){
									columnNode = new DefaultMutableTreeNode(c.getName());
									tableNode.add(columnNode);
								}
						}
					}
				}
			}
		}
		selectionTree.expandRow(0);
		selectionTree.expandRow(1);
		
	}


}
